package cn.chencaiju.blog.utils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import cn.chencaiju.blog.service.CategoryService;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class ServiceProxyUtils {
	/**
	 * 传入一个原始的service对象，
	 * 返回一个增强过ervice代理对象
	 * 
	 * 增强：在service方法调用之前加入处理：打开session
	 * 	    在service方法调用之后加入处理：关闭session、提交事务
	 * @param service
	 * @return
	 */
	public static Object createProxy(Object service) {
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(service.getClass());
		// 方法拦截器，原始对象上面调用任何方法，都会被代理对象拦截到
		enhancer.setCallback(new MethodInterceptor() {	
			@Override
			public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy methodProxy) throws Throwable {
				// 打开session
				SqlSessionFactory factory = SessionFactoryUtils.getFactory();
				SqlSession session = factory.openSession();
				
				// 使用反射，给原始service对象里面mapper进行初始化赋值
				Field field = service.getClass().getDeclaredField("mapper");
				Class<?> type = field.getType();
				field.setAccessible(true);
				
				// 动态的取到mapper字段的类型
				field.set(service, session.getMapper(type));
				
				// 执行原有的方法
				Object result = methodProxy.invoke(service, arg2);
				
				// 提交事务，关闭session
				session.commit();
				session.close();
				
				return result;
			}
		});
		
		return enhancer.create();
	}
}
